package com.google.code.chaotic;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import com.google.code.chaotic.dto.AdminDto;
import com.google.code.chaotic.dto.CommuterDto;
import com.google.code.chaotic.dto.CommutingHabitDto;
import com.google.code.chaotic.dto.CommutingServiceDto;
import com.google.code.chaotic.dto.HabitInServiceDto;
import com.google.code.chaotic.dto.HabitWaypointDto;
import com.google.code.chaotic.dto.LatLonDto;
import com.google.code.chaotic.dto.ServiceWaypointDto;
import com.google.code.chaotic.dto.UserDto;
import com.google.code.chaotic.model.Admin;
import com.google.code.chaotic.model.Commuter;
import com.google.code.chaotic.model.CommutingHabit;
import com.google.code.chaotic.model.CommutingService;
import com.google.code.chaotic.model.HabitInService;
import com.google.code.chaotic.model.HabitWaypoint;
import com.google.code.chaotic.model.LatLon;
import com.google.code.chaotic.model.ServiceWaypoint;
import com.google.code.chaotic.model.User;

public class ConversionUtil {

	public static Commuter dtoToEntity(CommuterDto dto) {
		if (dto == null)
			return null;
		Commuter entity = new Commuter();
		entity.setId(dto.getId());
		entity.setFirstName(dto.getFirstName());
		entity.setLastName(dto.getLastName());
		entity.setIcPassport(dto.getIcPassport());
		entity.setIssuingCountry(dto.getIssuingCountry());
		entity.setBirthDate(dto.getBirthDate());
		entity.setEmail(dto.getEmail());
		entity.setPhoneNo(dto.getPhoneNo());
		entity.setMale(dto.isMale());
		entity.setUsername(dto.getUsername());
		entity.setPasswordMd5(dto.getPasswordMd5());
		entity.setMembershipStart(dto.getMembershipStart());

		List<CommutingHabit> habits = new LinkedList<CommutingHabit>();
		for (CommutingHabitDto habitDto : dto.getCommutingHabits()) {
			CommutingHabit habitEntity = dtoToEntity(habitDto);
			habitEntity.setCommuter(entity);
			habits.add(habitEntity);
		}
		entity.setCommutingHabits(habits);
		return entity;
	}

	public static CommuterDto entityToDto(Commuter entity) {
		if (entity == null)
			return null;
		CommuterDto dto = new CommuterDto();
		entityToDto((User) entity, dto);

		dto.setIcPassport(entity.getIcPassport());
		dto.setIssuingCountry(entity.getIssuingCountry());
		dto.setBirthDate(entity.getBirthDate());
		dto.setPhoneNo(entity.getPhoneNo());
		dto.setMale(entity.isMale());
		dto.setMembershipStart(entity.getMembershipStart());

		List<CommutingHabitDto> habitDtos = new LinkedList<CommutingHabitDto>();
		for (CommutingHabit habit : entity.getCommutingHabits()) {
			CommutingHabitDto habitDto = entityToDto(habit);
			habitDto.setCommuter(dto);
			habitDtos.add(habitDto);
		}
		dto.setCommutingHabits(habitDtos);
		return dto;
	}

	public static AdminDto entityToDto(Admin entity) {
		if (entity == null)
			return null;
		AdminDto dto = new AdminDto();
		entityToDto((User) entity, dto);
		return dto;
	}

	public static CommutingHabitDto entityToDto(CommutingHabit entity) {
		if (entity == null)
			return null;
		CommutingHabitDto dto = new CommutingHabitDto();
		dto.setId(entity.getId());
		dto.setOrigin(entityToDto(entity.getOrigin()));
		dto.setDestination(entityToDto(entity.getDestination()));
		dto.setDepartureTime(entity.getDepartureTime());
		dto.setArrivalTime(entity.getArrivalTime());
		dto.setStartDate(entity.getStartDate());
		dto.setEndDate(entity.getEndDate());
		dto.setVersion(entity.getVersion());

		ArrayList<HabitWaypointDto> waypointDtos = new ArrayList<HabitWaypointDto>();
		for (HabitWaypoint point : entity.getWaypoints()) {
			HabitWaypointDto pointDto = entityToDto(point, dto);
			pointDto.setCommutingHabit(dto);
			waypointDtos.add(pointDto);
		}
		dto.setWaypoints(waypointDtos);
		return dto;
	}

	public static CommutingHabit dtoToEntity(CommutingHabitDto dto) {
		if (dto == null)
			return null;
		CommutingHabit entity = new CommutingHabit();
		entity.setId(dto.getId());
		entity.setOrigin(dtoToEntity(dto.getOrigin()));
		entity.setDestination(dtoToEntity(dto.getDestination()));
		entity.setDepartureTime(dto.getDepartureTime());
		entity.setArrivalTime(dto.getArrivalTime());
		entity.setStartDate(dto.getStartDate());
		entity.setEndDate(dto.getEndDate());
		entity.setVersion(dto.getVersion());

		ArrayList<HabitWaypoint> habitWaypoints = new ArrayList<HabitWaypoint>();
		for (HabitWaypointDto pointDto : dto.getWaypoints()) {
			HabitWaypoint pointEntity = dtoToEntity(pointDto, entity);
			habitWaypoints.add(pointEntity);
		}
		entity.setWaypoints(habitWaypoints);
		return entity;
	}

	public static HabitWaypointDto entityToDto( //
			HabitWaypoint entity, CommutingHabitDto habitDto) {

		if (entity == null)
			return null;
		HabitWaypointDto dto = new HabitWaypointDto();
		// BeanUtils.copyProperties(dto, entity);
		dto.setCommutingHabit(habitDto);
		dto.setPosition(entityToDto(entity.getPosition()));
		dto.setSequenceNo(entity.getSequenceNo());
		dto.setVersion(entity.getVersion());
		return dto;
	}

	public static HabitWaypoint dtoToEntity( //
			HabitWaypointDto dto, CommutingHabit habitEntity) {

		if (dto == null)
			return null;
		HabitWaypoint entity = new HabitWaypoint();
		// BeanUtils.copyProperties(entity, dto);
		entity.setCommutingHabit(habitEntity);
		entity.setPosition(dtoToEntity(dto.getPosition()));
		entity.setSequenceNo(dto.getSequenceNo());
		entity.setVersion(dto.getVersion());
		return entity;
	}

	public static ServiceWaypoint dtoToEntity( //
			ServiceWaypointDto dto, CommutingService serviceEntity) {

		if (dto == null)
			return null;
		ServiceWaypoint entity = new ServiceWaypoint();
		entity.setCommutingService(serviceEntity);
		entity.setSequenceNo(dto.getSequenceNo());
		entity.setPosition(dtoToEntity(dto.getPosition()));
		return entity;
	}

	public static ServiceWaypointDto entityToDto(ServiceWaypoint entity) {
		if (entity == null)
			return null;
		ServiceWaypointDto dto = new ServiceWaypointDto();
		// BeanUtils.copyProperties(dto, entity);
		dto.setSequenceNo(entity.getSequenceNo());
		dto.setPosition(entityToDto(entity.getPosition()));
		dto.setSequenceNo(entity.getSequenceNo());
		return dto;
	}

	public static LatLonDto entityToDto(LatLon entity) {
		if (entity == null)
			return null;
		LatLonDto dto = new LatLonDto();
		dto.setLatitude(entity.getLatitude());
		dto.setLongitude(entity.getLongitude());
		return dto;
	}

	public static LatLon dtoToEntity(LatLonDto dto) {
		if (dto == null)
			return null;
		LatLon entity = new LatLon();
		entity.setLatitude(dto.getLatitude());
		entity.setLongitude(dto.getLongitude());
		return entity;
	}

	public static CommutingService dtoToEntity(CommutingServiceDto dto) {
		if (dto == null)
			return null;
		CommutingService entity = new CommutingService();
		entity.setId(dto.getId());
		entity.setDepartureTime(dto.getDepartureTime());
		entity.setArrivalTime(dto.getArrivalTime());
		entity.setOrigin(dtoToEntity(dto.getOrigin()));
		entity.setDestination(dtoToEntity(dto.getDestination()));
		entity.setFinalized(dto.isFinalized());

		ArrayList<ServiceWaypoint> serviceWaypoints = new ArrayList<ServiceWaypoint>();
		for (ServiceWaypointDto pointDto : dto.getWaypoints()) {
			ServiceWaypoint pointEntity = dtoToEntity(pointDto, entity);
			serviceWaypoints.add(pointEntity);
		}
		entity.setWaypoints(serviceWaypoints);

		ArrayList<HabitInService> hisList = new ArrayList<HabitInService>();
		for (HabitInServiceDto hisDto : dto.getHabits()) {
			HabitInService hisEntity = dtoToEntity(hisDto, entity);
			hisList.add(hisEntity);
		}
		entity.setHabits(hisList);
		return entity;
	}

	public static CommutingServiceDto entityToDto(CommutingService entity) {
		if (entity == null)
			return null;
		CommutingServiceDto dto = new CommutingServiceDto();
		dto.setId(entity.getId());
		dto.decodedId = entity.getDecodedId();
		dto.setDepartureTime(entity.getDepartureTime());
		dto.setArrivalTime(entity.getArrivalTime());
		dto.setOrigin(entityToDto(entity.getOrigin()));
		dto.setDestination(entityToDto(entity.getDestination()));
		dto.setFinalized(entity.isFinalized());

		ArrayList<ServiceWaypointDto> waypointDtos = new ArrayList<ServiceWaypointDto>();
		for (ServiceWaypoint point : entity.getWaypoints()) {
			ServiceWaypointDto pointDto = entityToDto(point);
			pointDto.setCommutingService(dto);
			waypointDtos.add(pointDto);
		}
		dto.setWaypoints(waypointDtos);

		ArrayList<HabitInServiceDto> habitsDtos = new ArrayList<HabitInServiceDto>();
		for (HabitInService habit : entity.getHabits()) {
			HabitInServiceDto habitDto = entityToDto(habit, dto);
			habitsDtos.add(habitDto);
		}
		dto.setHabits(habitsDtos);

		return dto;
	}

	public static HabitInService dtoToEntity( //
			HabitInServiceDto hisDto, CommutingService serviceEntity) {

		if (hisDto == null)
			return null;
		HabitInService entity = new HabitInService();

		entity.setHabit(dtoToEntity(hisDto.getHabit()));
		entity.setHabitId(hisDto.getHabitId());

		entity.setService(serviceEntity);
		entity.setCancellingCode(hisDto.getCancellingCode());
		entity.setCancellationTime(hisDto.getCancellationTime());
		return entity;
	}

	public static HabitInServiceDto entityToDto( //
			HabitInService his, CommutingServiceDto serviceDto) {

		if (his == null)
			return null;
		HabitInServiceDto dto = new HabitInServiceDto();

		dto.setHabit(entityToDto(his.getHabit()));
		dto.setHabitId(his.getHabitId());

		dto.setService(serviceDto);
		dto.setCancellingCode(his.getCancellingCode());
		dto.setCancellationTime(his.getCancellationTime());
		return dto;
	}

	public static UserDto entityToDto(User entity) {
		if (entity instanceof Admin) {
			return entityToDto((Admin) entity);

		} else if (entity instanceof Commuter) {
			return entityToDto((Commuter) entity);

		} else {
			return entityToDto(entity, null);
		}
	}

	public static UserDto entityToDto(User entity, UserDto dto) {
		if (entity == null)
			return dto;
		dto.setId(entity.getId());
		dto.setUsername(entity.getUsername());
		dto.setPasswordMd5(entity.getPasswordMd5());
		dto.setEmail(entity.getEmail());
		dto.setFirstName(entity.getFirstName());
		dto.setLastName(entity.getLastName());
		return dto;
	}

}
